/** \file
* Declarations for the basic Twitter element class.
* This file is part of Chorus, available at
* http://code.google.com/p/chorus-twitter/ . This file and all associated files
* and derivative works are bound by the terms of the LGPL 3.0 license,
* available at http://www.gnu.org/licenses/lgpl-3.0-standalone.html .
* \par Subversion URL:
* \$URL: http://chorus-twitter.googlecode.com/svn/branches/cpp/src/xml/XmlElement.hpp $
* \version \$Rev: 153 $
* \date    \$Date: 2010-04-06 07:43:42 +0000 (Tue, 06 Apr 2010) $
*/

#pragma once

#include <map>

#include "XmlProperty.hpp"

namespace std
{
	/// The STL "less" predicate, specialized for a null-terminated string.
	/// This is used in the STL map class.
	/// \param rleft  The left string.
	/// \param rright The right string.
	/// \return Whether the left string should come before the right string in
	///         alphabetical order. ("Alphabetical" in this case is just ASCII
	///         order.)
	template <>
	bool less<const char*>::operator()(const char *const &rleft,
		const char *const &rright) const;
}

/// The abstract Twitter element class. Anything in the Twitter system that has
/// an ID is derived from this.
class XmlElement
{
protected:
	/// The constructor. Cannot be called directly.
	XmlElement();
public:
	/// The destructor.
	virtual ~XmlElement();

	/// Get this element's ID.
	/// \return The ID.
	unsigned getId() const
	{
		return prop_id.get();
	}

	/// Get the property associated with a property name.
	/// \param key The property string to look for in the map.
	/// \return A pointer to the property if it was found, or 0 otherwise.
	XmlProperty *getProp(const char *key)
	{
		MapIterType found = props.find(key);
		if (found == props.end())
			return 0;
		return found->second;
	}

protected:
	/// Insert a new property. This is called by children of this class in
	/// their constructor.
	/// \param key  The property name string.
	/// \param prop A pointer to the associated property object.
	void insertProp(const char *key, XmlProperty *prop)
	{
		std::pair<const char*, XmlProperty*> newpair(key, prop);
		props.insert(newpair);
	}

private:
	/// The property map type.
	typedef std::map<const char*, XmlProperty*> MapType;
	/// The property map iterator type.
	typedef MapType::iterator MapIterType;
	/// The property map constant iterator type.
	typedef MapType::const_iterator MapConstIterType;
	/// The map of property strings to their respective properties.
	MapType props;
public:
	/// The ID of this element.
	TypedXmlProperty<unsigned> prop_id;
};
